#include <iostream>
#include <cstring>
using namespace std;

class String
{
	public :
		int m_len;
		char *m_str;

	public :
		String(const char *str = NULL);
		String(const String& other);
		~String();
		String& operator=(const String& other);
		String& operator=(const char *str);
		const char& operator[](unsigned int index) const;
		char& operator[](unsigned int index);

		friend String operator+(const String& ls, const String& rs);
		friend bool operator==(const String& ls, const String& rs);
		friend istream& operator>>(istream& in, const String& s);
		friend ostream& operator<<(ostream& out, const String& s);

	protected :
};

String :: String(const char *str)
{
	if(NULL == str)
	{
		m_len = 1;
		m_str = new char[m_len];
		*m_str = '\0';
	}
	else
	{
		m_len = strlen(str);
		m_str = new char[m_len + 1];
		strcpy(m_str, str);
	}
}

String :: String(const String& other)
{
	m_len = strlen(other.m_str);
	m_str = new char[m_len + 1];
	strcpy(m_str, other.m_str);
}

String :: ~String()
{
	delete [] m_str;
}

String& String :: operator=(const String& other)
{
	if(this != &other)
	{
		delete [] m_str;
		m_len = strlen(other.m_str);
		m_str = new char[m_len + 1];
		strcpy(m_str, other.m_str);
	}

	return *this;
}

String& String :: operator=(const char *str)
{
	if(NULL == str)
	{
		delete [] m_str;
		m_len = 1;
		m_str = new char[m_len];
		*m_str = '\0';
	}
	else
	{
		delete [] m_str;
		m_len = strlen(str);
		m_str = new char[m_len + 1];
		strcpy(m_str, str);
	}

	return *this;
}

const char& String :: operator[](unsigned int index) const
{
	static char c = '\0';

	if(index < m_len)
	{
		return m_str[index];
	}
	else
	{
		cout << "Out of range !" << endl;
		return c;
	}
}

char& String :: operator[](unsigned int index)
{
	static char c = '\0';

	if(index < m_len)
	{
		return m_str[index];
	}
	else
	{
		cout << "Out of range !" << endl;
		return c;
	}
}

String operator+(const String& ls, const String& rs)
{
/*
	String temp;
	temp.m_str = new char[strlen(ls.m_str) + strlen(rs.m_str) + 1];

	for(; *ls.m_str != '\0'; ls.m_str++);
	for(; *rs.m_str != '\0'; ls.m_str++, rs.m_str++)
		*ls.m_str = * rs.m_str;
	*ls.m_str = '\0';

	temp.m_str = ls.m_str;
	return temp;
*/

	String temp;
	temp.m_str = new char[strlen(ls.m_str) + strlen(rs.m_str) + 1];
	temp.m_str = strcat(ls.m_str, rs.m_str);
	return temp;

}

bool operator==(const String& ls, const String& rs)
{
/*
	if(ls.m_len != rs.m_len || strlen(ls.m_str) != strlen(rs.m_str))
	{
		return false;
	}
	else
	{
		if(strlen(ls.m_str) == strlen(rs.m_str))
		{
			for(; *ls.m_str != '\0', *rs.m_str != '\0'; ls.m_str++, rs.m_str++)
			{
				if(*ls.m_str == *rs.m_str)
					return true;
			}
		}
	}
*/
	if(strcmp(ls.m_str, rs.m_str) == 0)
	{
		return true;
	}
	else 
	{
		return false;
	}
}

istream& operator>>(istream& in, const String& s)
{
	cout << "<My input()>" << endl;
	in >> s.m_str;
	return in;
}

ostream& operator<<(ostream& out, const String& s)
{
	out << "<My output()>" << endl << "String : " << s.m_str;
	return out;
}

char func(const String& s)
{
	char c = s[1];
	return c;
}

int main()
{
	String s1("Hello");
	String s2("World !");
	String s3 = s1;
	String s4;
	String s5 = "hdu";

	String s7("nice");
	String s8 = "nice";

	String s6 = s1 + s2;
	cout << "<重载相加函数+>" << endl << "s6 = " << s6 << endl;

	cout << "<重载下标操作符（右值操作）>" << endl << "s1[1] = : " << s1[1] << endl;
	cout << "<重载下标操作符（超数据范围）>" << endl << "s1[10] = : " << s1[10] << endl;
	cout << "<重载下标操作符const>" << endl << "func()  : " << func(s1) << endl;

	s2[0] = 'b';
	cout << "<重载下标操作符（左值操作）>" << endl << s2 << endl;

	cout << "<重载赋值操作（字符串）>" << endl << s5 <<endl;

	cout << "<重载输入输出操作符>" << endl;
	cin >> s4;
	cout << s4 << endl;

	bool b1;
	b1 = s7 == s8;
	cout << s7 << endl << s8 << endl;
	cout << "<重载关系操作符==>" << endl << "Bool : " << b1 << endl;

//	cout << s1 << endl;
//	cout << s2 << endl;
//	cout << s3 << endl;
}
